/**
 * @file HttpException filter
 * @module filter/error
 * @author Surmon <https://github.com/surmon-china>
 */

import lodash from 'lodash'
import { isDevMode } from '@app/app.environment'
import { ResponseStatus, HttpResponseError, ExceptionOption, ResponseMessage } from '@app/interfaces/http.interface'
import { ExceptionFilter, Catch, HttpException, ArgumentsHost, HttpStatus } from '@nestjs/common'

/**
 * @class HttpExceptionFilter
 * @classdesc 拦截全局抛出的所有异常，同时任何错误将在这里被规范化输出 THttpErrorResponse
 */
@Catch()
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const request = host.switchToHttp().getRequest()
    const response = host.switchToHttp().getResponse()
    const status = exception.getStatus() || HttpStatus.INTERNAL_SERVER_ERROR
    const errorOption: ExceptionOption = exception.getResponse() as ExceptionOption
    const isString = (value): value is ResponseMessage => lodash.isString(value)
    const errMessage = isString(errorOption) ? errorOption : errorOption.message
    const errorInfo = isString(errorOption) ? null : errorOption.error
    const parentErrorInfo = errorInfo ? String(errorInfo) : null
    const isChildrenError = errorInfo?.status && errorInfo?.message
    const resultError = (isChildrenError && errorInfo.message) || parentErrorInfo
    const resultStatus = isChildrenError ? errorInfo.status : status
    const data: HttpResponseError = {
      status: ResponseStatus.Error,
      message: errMessage,
      error: resultError,
      debug: isDevMode ? exception.stack : null,
    }
    // 对默认的 404 进行特殊处理
    if (status === HttpStatus.NOT_FOUND) {
      data.error = `资源不存在`
      data.message = `接口 ${request.method} -> ${request.url} 无效`
    }
    return response.status(resultStatus).jsonp(data)
  }
}
